import { PackageManagerTabs } from '@theme';

# 自定义页面

Rspress 提供了多种方式能让你自定义页面的内容，包括：

- 添加自定义全局组件；
- 添加自定义全局样式；
- 自定义页面布局结构。

## 自定义全局组件

某些场景下，你可能需要在页面中添加一些自定义的全局组件，Rspress 提供了一个配置项 `globalUIComponents` 来实现这个功能。

### 使用方法

在 `rspress.config.ts` 中添加以下配置：

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';

export default defineConfig({
  globalUIComponents: [path.join(__dirname, 'components', 'MyComponent.tsx')],
});
```

`globalUIComponents` 的每一项可以是一个字符串，代表组件的文件路径；也可以是一个数组，第一项为组件的文件路径，第二项为组件的 props 对象，比如：

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';

export default defineConfig({
  globalUIComponents: [
    [
      path.join(__dirname, 'components', 'MyComponent.tsx'),
      {
        foo: 'bar',
      },
    ],
  ],
});
```

import GlobalUIComponents from '@zh/fragments/global-ui-components';

<GlobalUIComponents />

## 自定义样式

某些场景下，你可能需要在主题 UI 的基础上添加一些全局样式，Rspress 提供了一个配置项 `globalStyles` 来实现这个功能。

### 使用方法

在 `rspress.config.ts` 中添加以下配置：

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';

export default defineConfig({
  globalStyles: path.join(__dirname, 'styles/index.css'),
});
```

然后可以添加以下代码：

```css
/* styles/index.css */
:root {
  --rp-c-brand: #f00;
}
```

这样 Rspress 会自动搜集所有的全局样式并合并到最终的样式文件中。

下面列举一些常用的全局样式：

```css
/* styles/index.css */

:root {
  /* 修改主题色 */
  --rp-c-brand: #f00;
  --rp-c-brand-dark: #ffa500;
  --rp-c-brand-darker: #c26c1d;
  --rp-c-brand-light: #f2a65a;
  --rp-c-brand-lighter: #f2a65a;
  /* 修改左侧侧边栏宽度 */
  --rp-sidebar-width: 280px;
  /* 修改右侧大纲栏宽度 */
  --rp-outline-width: 256px;
  /* 修改代码块标题背景 */
  --rp-code-title-bg: rgba(250, 192, 61, 0.15);
  /* 修改代码块内容背景 */
  --rp-code-block-bg: rgba(214, 188, 70, 0.05);
}
```

> 如果想了解更多内部的全局样式，可以查看 [vars.css](https://github.com/web-infra-dev/rspress/blob/main/packages/theme-default/src/styles/vars.css)

### Tailwind CSS

要在 Rspress 中使用 Tailwind CSS，你可以按照以下步骤操作：

1. 安装 Tailwind CSS：

<PackageManagerTabs command="install tailwindcss -D" />

2. 创建一个包含 `tailwindcss` 插件的 `postcss.config.js` 文件：

```js title="postcss.config.js"
module.exports = {
  plugins: {
    tailwindcss: {},
  },
};
```

3. 创建一个 `tailwind.config.js` 文件，并确保 `content` 包含了所有使用 Tailwind CSS 的文件：

```js title="tailwind.config.js"
module.exports = {
  content: ['./src/**/*.tsx', './docs/**/*.mdx'],
  theme: {
    extend: {},
  },
  plugins: [],
};
```

4. 在你的 CSS 样式文件中添加 Tailwind 指令，参考 [自定义样式](#自定义样式)：

```css title=styles/index.css
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
```

> 请参考官方 [Tailwind CSS 文档](https://tailwindcss.com/docs/installation/using-postcss) 了解最新用法。

## 自定义布局结构

Rspress 提供了 `pageType` 配置来让你自定义页面的布局结构。

### 使用 pageType

Rspress 的约定式路由支持了两种路由，一种是文档路由，即用 md(x) 文件编写的页面，另一种是组件路由，即 `.jsx/.tsx` 文件编写的页面。

对于前者，你可以在 frontmatter 中添加 `pageType` 字段来指定页面的布局结构，比如：

```mdx title="foo.mdx"
---
pageType: custom
---
```

对于后者，你可以添加如下的导出来指定 `pageType`：

```tsx title="foo.tsx"
// 导出 frontmatter 对象，其含义与 md(x) 文件中的 frontmatter 一致
export const frontmatter = {
  // 声明布局类型
  pageType: 'custom',
};
```

pageType 可以配置为如下的值：

import PageType from '@zh/fragments/page-type.mdx';

<PageType />

### 使用细粒度开关

除了 `pageType` 页面布局级别的配置之外，Rspress 还提供了更细粒度的开关，你可以在 frontmatter 配置其它的字段，这些字段及其含义如下：

- `navbar`：是否展示顶部导航栏，当你想要隐藏顶部导航栏时，可以配置为 `false`；
- `sidebar`：是否展示侧边栏，当你想要隐藏侧边栏时，可以配置为 `false`；
- `outline`：是否展示大纲栏，当你想要隐藏大纲栏时，可以配置为 `false`；
- `footer`：是否展示页脚，当你想要隐藏页脚时，可以配置为 `false`；
- `globalComponents`: 是否展示全局组件，当你想要隐藏全局组件时，可以配置为 `false`。

示例：

```mdx title="foo.mdx"
---
navbar: false
sidebar: false
outline: false
footer: false
globalUIComponents: false
---
```

### 使用 URL 参数开关

除此之外，你还可以使用 URL 参数在运行时控制页面的布局结构，比如：

```bash
# 隐藏导航栏和右侧大纲栏
http://YOUR_DOMAIN/foo?navbar=0&outline=0
```

通过 URL 参数，你可以在不修改源码的情况下，快速地调整页面的布局结构，这些参数具体包括：

- `navbar`：是否展示导航栏，当你想要隐藏顶部导航栏时，可以配置为 `0`；
- `sidebar`：是否展示侧边栏，当你想要隐藏侧边栏时，可以配置为 `0`；
- `outline`：是否展示大纲栏，当你想要隐藏大纲栏时，可以配置为 `0`；
- `footer`：是否展示页脚，当你想要隐藏页脚时，可以配置为 `0`；
- `globalUIComponents`：是否展示全局组件，当你想要隐藏全局组件时，可以配置为 `0`。

## 自定义标签

### 自定义 head 标签

在 `rspress.config.ts` 中，你可以为所有页面设置 HTML 的 metadata（即 head 标签）。我们在 [基础配置 - head](/api/config/config-basic#head) 中详细解释了这一点。

### 生成 metadata 标签

在 frontmatter 中，你还可以自定义页面的 metadata 标签以进行 SEO 优化。

例如，如果你想在 `<head>` 标签中添加 `<meta name="description" content="This is description">`，你可以这样使用 frontmatter：

```md title="example.mdx"
---
head:
  - - meta
    - name: title
      content: This is title
  - - meta
    - name: description
      content: This is description
---
```

### Open Graph 标签

[Open Graph](https://ogp.me/) 是一种网页元数据协议，用于控制页面在社交媒体平台上分享时的显示效果。

Rspress 会自动为每个页面注入以下 Open Graph meta 标签：

- `og:type`：固定值为 `website`
- `og:title`：自动使用当前页面的标题

如果你需要自定义更多 Open Graph 标签（如 `og:image`、`og:title` 等），请参考 [frontmatter 配置](/api/config/config-frontmatter#head)。
